package Commons;


import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;


/**Questa classe implementa il Servizio che permette la ricezione affidabile dei files attraverso il protocollo UDP.
 *
 * @author Team5
 */

public class ServerTrasferimentoFileUDP implements Runnable {

    private int port ;
    private int bufferDatagramSize;
    private byte buffDatagram[];
    private boolean condizione=true;
    private int bufferFileSize ;
    private int bufferContatoreSize ;
    private byte buffContatore [] ;

    private String path;
    
 /**Costruttore di default. Associa come predefiniti i seguenti parametri :
     * <ul>
     *      <li><b>port=</b>12341</li>
     *      <li><b>path=</b>""</li>
     * </ul>
     * @throws UnknownHostException
     */
    public ServerTrasferimentoFileUDP() {
        port = 12341;
        path="";
      
    }


     /**Costruttore con parametri in ingresso relativi al path di ricezione dei files e la porta del servizio.
     *
     * @param path il percorso relativo alla cartella di Download
     * @param portaServizio è la porta in cui viene lanciato l'ascoltatore per la richiesta dell'invio dei file
     */
    public ServerTrasferimentoFileUDP(String path, int portaServizio ) {
        this.port = portaServizio;
        this.path=path;
        
    }

    /**
     * run() del Thread per il lancio del servizio.
     */

    public void run() {
         DatagramSocket serverSocket =null;

        try
            {
            System.out.println("SERVER_TRASFERIMENTO_FILEUDP____RUN()");
            serverSocket=new DatagramSocket(port);
            byte[] receiveData = new byte[1024];
            byte[] sendData = new byte[1024];
           


         while(condizione)
         {

            //In ascolto per la richiesta di invio del file
            DatagramPacket receiveEPacket = new DatagramPacket(receiveData, receiveData.length);
            serverSocket.receive(receiveEPacket);

            //Prelevo la stringa di comando
            String comando = new String(receiveEPacket.getData());

            //Dalla stringa di comando recupero il nome
            //con cui salvare il file, il numero di pacchetti attesi
            //e la dimensione del padding dell'ultimo pacchetto
            String nomeNuovoFile = comando.split(":")[1];
            int numeroDiPacchetti = Integer.parseInt((comando.split(":")[2]).trim());
            int dimensionePadding = Integer.parseInt((comando.split(":")[3]).trim());

            //Dal pacchetto datagram ricevuto ricavo l'indirizzo e la porta del client
            //che mi invierà il file
            InetAddress clientAddress = receiveEPacket.getAddress();
            int clientPort = receiveEPacket.getPort();


            String path =this.path+nomeNuovoFile;
            ThreadRicezioneFileUDP trfUDP = new ThreadRicezioneFileUDP(path,numeroDiPacchetti,dimensionePadding);


            //Ricavo il numero della porta del socket appena creato,
            //e lo memorizzo nella variabile sendData come array di byte

            //Avvio del thread che si occuperà della singola ricezione del file da parte del client
            Integer iportaFile =  trfUDP.getPortaRicezioneFile();
            Thread t1=new Thread(trfUDP);
            t1.start();


            String portaFile = iportaFile.toString();
            sendData = portaFile.getBytes();

            //Creazione e invio al client di un pacchetto contenente il numero di porta
            //dedicata su cui trasferire il file
            DatagramPacket sendPacket = new DatagramPacket(sendData, sendData.length, clientAddress, clientPort);
            serverSocket.send(sendPacket);

            System.out.println("Fine connessione per l'invio del numero di porta");
          }
          System.out.println("SERVERTRASFERIMENTOFILE UDP_______FINERUN");








            }
        catch(Exception ex)
        {
            System.out.println("SERVERTRASFERIMENTOFILE UDP_______CLOSE");
            if(serverSocket!=null){serverSocket.close();}
           // ex.printStackTrace();

        }
          //Chiudo la connessione
        finally{/*serverSocket.close();*/}
    }
    public void setCondizioneFalse(){
        this.condizione=false;
    }


}